package com.pluto.sort;

/**
 * 插入排序
 *
 * 一个一个的,将被插入元素插入到指定位置,
 * 在插入的过程中会有已存在元素位置的移动,可以将这种方式与斗地主时的抽牌联系起来
 */
public class Insertion {

    public static void sort(Comparable[] a) {
        int N = a.length;
        for (int i = 1; i < N; i++) {
            /*
             * 将a[i]插入到a[0] a[1]... a[j -1]中,最坏的情况每队相邻元素都可能移动
             * 最开始只有a[0],然后添加a[1]到a[0],添加a[2]到a[0],a[1],添加a[3]到a[0],a[1],a[2]
             * 由于左侧部分是已经排好序的,a[j]会被添加到第一个a[j] > a[j - 1]的地方为止
             */
            for (int j = i; j > 0 && less(a[j], a[j - 1]); j--) {
                exch(a, j , j - 1);
            }
        }
    }

    /**
     * 交换数组指定的两个位置上的元素
     * @param a
     * @param i
     * @param j
     */
    private static void exch(Comparable[] a, int i, int j) {
        Comparable temp = a[i];
        a[i] = a[j];
        a[j] = temp;
    }

    private static boolean less(Comparable a, Comparable b) {
        return a.compareTo(b) < 0;
    }

    private static void show(Comparable[] a) {
        for (int i = 0; i < a.length; i++) {
            System.out.println(a[i]);
        }
        System.out.println();
    }

    public static void main(String[] args) {
        Integer[] a = { 3, 54, 12, 12, 33, 1, 656, 5, 87, 90 };
        sort(a);
        show(a);
    }
}
